package com.appcan.base;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.naming.InitialContext;
import javax.naming.NamingException;



/**
 * 获取�?��调用的EJB接口 在不明确是否是调用远程接口的情况下，使用getClient方法�?
 * 
 * 在明确知道是调用远程接口的情况下，可以调用getRemoteClient方法�?
 * 
 * 在明确知道调用local接口的情况下，使用getLocalClient方法
 */
public class BoClient {
	public enum EJB_TYPE {
		local, remote
	}

	private static final int MAXCACHESIZE = 100;

	static EJB_TYPE ejbType;

	/**
	 * 远程接口使用的上下文哈希表；key是提供远程接口的系统id，value是上下文
	 */
	static HashMap<Integer, InitialContext> jndiContenxtMap;
	/**
	 * 本地接口的上下文
	 */
	static InitialContext localContext;

	//清除本地调试代码后，�?��根据该属性处理SessionBean的名�?
	static boolean isSessionBeanNameIncludeStreetID;

	/**
	 * <p>
	 * 获取EJB远程接口�?
	 * <p>
	 * 作�?：jiangwf<br>
	 * 日期�?008-4-14
	 * 
	 * @param beanName
	 *            EJB接口的实现类类名
	 * @param remoteIP
	 *            部署该EJB的服务器IP
	 * @return Object EJB接口实例,null表示该接口没有找到或者出现异�?
	 */
	public static Object getRemoteClient(String beanName, String remoteIP) {
		if (beanName == null || remoteIP == null) {
			return null;
		}
		Object ret = null;
		remoteLock.lock();
		try {						
			InitialContext context = initialContexts.get(remoteIP);
			if (context == null) {
				context = BaseFunction.createInitialContext(remoteIP + ":1099");
				initialContexts.put(remoteIP, context);
				ejbType = EJB_TYPE.remote;
			}

			ret = context.lookup(new StringBuilder(beanName).append("/")
					.append(ejbType.toString()).toString());
		} catch (NamingException e) {
			RunTimeLogger.error(BoClient.class, "NamingException", e);
		} finally {
			remoteLock.unlock();
			clearContexts();			
		}
		return ret;
	}

	private static void clearContexts() {
		if (initialContexts.size() >= MAXCACHESIZE) {
			initialContexts.clear();
		}
	}

	private static Lock remoteLock = new ReentrantLock();
	private static Lock localLock = new ReentrantLock();
	private static Map<String, InitialContext> initialContexts = new HashMap<String, InitialContext>();

	/**
	 * 获取EJB本地接口。效果与getLocalClient(sessionBeanName)相同�?
	 * 
	 * @param sessionBeanName
	 *            EJB接口的实现类类名
	 * @return EJB接口实例,null表示该接口没有找到或者出现异�?
	 * 
	 */
	public static Object getClient(String sessionBeanName) {
		return getLocalClient(sessionBeanName);
	}

	/**
	 * 获取local接口
	 * 
	 * @param sessionBeanName
	 *            EJB接口的实现类类名
	 * @return EJB接口实例,null表示该接口没有找到或者出现异�?
	 */
	public static Object getLocalClient(String sessionBeanName) {
		Object ret = null;
		try {
			localLock.lock();
			if (localContext == null) {
				localContext = BaseFunction
						.createInitialContext("localhost:1099");
			}
			ret = localContext.lookup(sessionBeanName + "/local");
		} catch (NamingException e) {
			RunTimeLogger.error(BoClient.class, "NamingException", e);
		} finally {
			localLock.unlock();
		}
		return ret;
	}

	/**
	 * <p>
	 * 原移动商务接口�?prefix不起作用。该方法等同�?getClient(String sessionBeanName)
	 * <p>
	 * 作�?：jiangwf<br>
	 * 日期�?008-4-14
	 * 
	 * @param prefix
	 * @param sessionBeanName
	 * @return Object
	 */
	public static Object getClient(String prefix, String sessionBeanName) {
		return getClient(sessionBeanName);
	}

	/**
	 * <p>
	 * 原移动商务接口�?prefix不起作用。该方法等同�?getLocalClient(String sessionBeanName)
	 * <p>
	 * 作�?：jiangwf<br>
	 * 日期�?008-4-14
	 * 
	 * @param prefix
	 * @param sessionBeanName
	 * @return Object
	 */
	public static Object getLocalClient(String prefix, String sessionBeanName) {
		return getLocalClient(sessionBeanName);
	}

	public static InitialContext getLocalContext() {
		try {
			localLock.lock();
			if (localContext == null) {
				localContext = BaseFunction
						.createInitialContext("localhost:1099");
			}
		} catch (NamingException e) {
			RunTimeLogger.error(BoClient.class, "NamingException", e);
		} finally {
			localLock.unlock();
		}
		return localContext;
	}
}
